/**
	License:		Artistic license 2.0 (see license.txt, also available online at http://www.perlfoundation.org/artistic_license_2_0)
	Authors:		OrbitalLab (http://www.orbitallab.ru/moonglide/), 2007-2009

	File:			TRMMeshIO.d
	Description:	mesh loading for *.trm files
	Date:			31.01.2007 by Jurec
*/
module moonglide.resources.io.mesh.trm.TRMMeshIO;

import
	tango.io.model.IConduit,

	moonglide.resources.io.mesh.MeshIO,
	moonglide.resources.resproc.mesh.ResPMesh,
	moonglide.resources.Management;

//================================================================
/// mesh io provider class
//================================================================
class CMeshTRMIOProvider : CMeshIOProvider
{
	protected:
		void ReadTriObj( InputStream stream, CResMesh M1 )
		{
			int NumIndices, NumVerts, NumUV, NumNorm, tmp = 0;

			stream.read( (cast(void*)&NumIndices)[0..4] );
			stream.read( (cast(void*)&NumVerts)[0..4] );
			stream.read( (cast(void*)&tmp)[0..4] );

			NumUV = (tmp==0) ? 0 : NumVerts;

			stream.read( (cast(void*)&NumNorm)[0..4] );

			M1.fields["Index"].SetLength(NumIndices);
			M1.fields["Vertex"].SetLength(NumVerts);
			M1.fields["TexCoord"].SetLength(NumUV);
			M1.fields["Normal"].SetLength(NumVerts);

			for( uint i = 0; i < NumIndices; i++ )
				stream.read( (cast(void*)&M1.fields["Index"].data.UInt[i])[0..4] );

			for( uint i = 0; i < NumVerts; i++ )
				stream.read( (cast(void*)&M1.fields["Vertex"].data.Vec3[i])[0..12] );

			for( uint i = 0; i < NumUV; i++ )
				stream.read( (cast(void*)&M1.fields["TexCoord"].data.Vec2[i])[0..8] );

			for( uint i = 0; i < NumVerts; i++ )
				stream.read( (cast(void*)&M1.fields["Normal"].data.Vec3[i])[0..12] );

			genMeshTangentSpace( M1 );
		}


		CResMaterial ReadMaterial( InputStream stream, char[] name )
		{
			auto Mat = CResMaterial( name ~ "_TRMTriMaterial" );

			Vector3f Col;

			stream.read(( cast(void*)&Col )[0..3] );
			Mat.vectors4["ambient"] = Vector4f( Col );

			stream.read(( cast(void*)&Col )[0..3] );
			Mat.vectors4["diffuse"] = Vector4f( Col );

			stream.read(( cast(void*)&Col )[0..3] );
			Mat.vectors4["specular"] = Vector4f( Col );

			byte sh = 30;

			stream.read( (cast(void*)&sh)[0..1] );
			Mat.ints["shininess"] = sh;

			int length = 0;

			stream.read(( cast(void*)&length )[0..4] );

			if( length > 0 )
			{
				char[] FileN;
				FileN.length = length;
				stream.read(( cast(void*)&FileN )[0..length] );
			}

			return Mat;
		}

	public:
		void Load( char[] extension, ref IResource res, InputStream stream, uint streamsize )
		{
			int Head = 0;

			const int HEADER_TRI_OBJ	= 1;
			const int HEADER_MAT		= 100;

			while( stream.read(( cast(void*)&Head)[0..4] ) != stream.Eof ) // should we read again with reader to move filepointer?.. I suppose that no.
			{
				switch( Head )
				{
					case HEADER_TRI_OBJ:
						auto mesh = cast(CResMesh)res;
						ReadTriObj( stream, mesh );
						return;

					case HEADER_MAT:
		//				auto mat = ReadMaterial( stream, res.id ); //how?
		// NOTE (Digited#): really, how?
						break;

					default: break;
				}
			}

		}

		bool Save( char[] format, IResource res, inout Array buf ) { return false; }
		void CreateErrorResourceData( IResource res, char[] errorResName ) {}

		char[] GetResourceClass() { return CResMesh.classinfo.name; }
}
